//
//  AnalysisView.swift
//  MyCloset
//
//  Created by 牟好好 on 2024/10/27.
//

import SwiftUI

struct AnalysisView: View {
    let image: UIImage
    @ObservedObject var coreVm = CoreDataViewModel.shared
    @EnvironmentObject var captureViewModel: CaptureViewModel
    @StateObject var fileVm = FileManagerViewModel()
    @EnvironmentObject var styleVm: ClothStylesViewModel
    @Binding var isShowingCamera: Bool
    @Binding var isUploadPhoto: Bool
    @State private var selectedType: String = ""
    @State private var selectedThickness: String = ""
    @State private var selectedColors: Set<String> = []
    @State private var selectedStyle: Set<String> = []
    @State private var typeIndex: Int?
    @State private var isModelEnabled: Bool = false
    @State private var isShowSheet: Bool = false
    var result: String {
        return generateResult()
    }
    var paddingValue = boundsWidth * 0.05
    @Namespace var leadingID
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(alignment: .leading, spacing: 20) {
                Group {
                    Image(uiImage: image)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: boundsWidth * 0.8)
                        .cornerRadius(12)
                    
                    HStack {
                        Button(action: {
                            isModelEnabled = true
                            detectType()
                            detectStyle()
                        }) {
                            Text("自动识别")
                                .frame(width: boundsWidth * 0.5)
                                .padding(.all, 10)
                                .background(.yellow)
                                .cornerRadius(10)
                        }
                        
                        Button {
                            captureViewModel.capturedImage = nil
                        } label: {
                            Image(systemName: "camera.circle")
                                .frame(width: boundsWidth * 0.2)
                                .padding(.all, 10)
                                .background(.yellow)
                                .cornerRadius(10)
                        }
                    }
                    .frame(alignment: .center)
                    .font(.system(size: 20, weight: .bold))
                    .foregroundStyle(.black)
                    
                    if isModelEnabled {
                        TipView(text: "模型识别多有不准，如有不准请手动修改(您自定义的样式无法被识别)")
                    }
                }
                .frame(width: boundsWidth * 0.9)
                
                Text("选择部位：")
                    .font(.system(size: 25, weight: .bold))
                ScrollPaddingFrameView(paddingValue: paddingValue, content: ForEach(clothTypes, id: \.self) { type in
                    HStack {
                        RadioButton(isSelected: selectedType == type, type: type) {
                            selectedType = type
                        }
                    }
                })
                
                if let index = typeIndex, index == 0 || index == 1 {
                    Text("选择厚度：")
                        .font(.system(size: 25, weight: .bold))
                    ScrollPaddingFrameView(paddingValue: paddingValue, content: ForEach(clothThickness, id: \.self) { thickness in
                        HStack {
                            RadioButton(isSelected: selectedThickness == thickness, type: thickness) {
                                selectedThickness = thickness
                            }
                        }
                    })
                }
                
                let rows = Array(repeating: GridItem(.flexible()), count: 2)
                
                Text("选择颜色：")
                    .font(.system(size: 25, weight: .bold))
                ScrollPaddingFrameView(paddingValue: paddingValue, content: LazyHGrid(rows: rows) {
                    ForEach(clothColors, id: \.self) { color in
                        ColorButton(isChecked: selectedColors.contains(color), color: color) {
                            if selectedColors.contains(color) {
                                selectedColors.remove(color)
                            } else {
                                selectedColors.insert(color)
                            }
                        }
                    }
                })
                
                // 这里可以加上示例样式图片
                if let index = typeIndex {
                    HStack {
                        Text("选择样式：")
                            .font(.system(size: 25, weight: .bold))
                        Spacer()
                        Button {
                            // TODO:打开指引界面，每个类型放一张图，尽量压缩
                            isShowSheet = true
                        } label: {
                            Image(systemName: "questionmark.circle")
                                .foregroundStyle(.yellow)
                                .font(.system(size: 25))
                        }
                    }
                    
                    ScrollViewReader { proxy in
                        ScrollView(.horizontal, showsIndicators: false) {
                            HStack {
                                // 左边距与滚动到顶部的标志
                                Spacer(minLength: paddingValue)
                                    .id(leadingID)
                                
                                ForEach(styleVm.styleList[index], id: \.self) { style in
                                    Checkbox(isChecked: selectedStyle.contains(style), style: style) {
                                        if selectedStyle.contains(style) {
                                            selectedStyle.remove(style)
                                        } else {
                                            selectedStyle.insert(style)
                                        }
                                    }
                                    if index != styleVm.styleList.count - 1 {
                                        Spacer(minLength: 15)
                                    }
                                }
                                
                                Spacer(minLength: paddingValue)
                            }
                            .frame(height: 30)
                        }
                        .padding(.horizontal, -paddingValue)
                        .onChange(of: index) { _ in
                            proxy.scrollTo(leadingID)
                        }
                    }
                }
                
                if result != "" {
                    Text(result)
                        .font(.system(size: 20, weight: .bold))
                        .padding(.all, 10)
                        .overlay {
                            RoundedRectangle(cornerRadius: 12).stroke(.yellow, lineWidth: 2)
                        }
                }
                
                Button(action: {
                    if selectedType != "" {
                        if let imageData = image.jpegData(compressionQuality: 0.3),
                           let compressedImage = UIImage(data: imageData) {
                            // 新增记录
                            let id = UUID()
                            fileVm.saveImage(image: compressedImage, id: id) { path in
                                coreVm.addClothes(id: id, imageURL: path, features: result)
                            }
                        }
                    }
                }, label: {
                    Text("保存")
                        .font(.headline)
                        .foregroundStyle(.black)
                        .frame(height: 45)
                        .frame(maxWidth: .infinity)
                        .background(selectedType == "" ? .gray : .yellow)
                        .cornerRadius(10)
                })
                .padding(.horizontal)
                .disabled(selectedType == "")
                
                Spacer(minLength: boundsHeight * 0.1 + safeAreaBottom)
            }
            .padding(.horizontal, boundsWidth * 0.05)
        }
        // 根据类型决定样式，如毛衣只适合上装，直筒靴只适合鞋子
        .onChange(of: selectedType) { _ in
            selectedStyle.removeAll()
            selectedThickness = ""
            typeIndex = clothTypes.firstIndex(of: selectedType)
            if isModelEnabled {
                detectStyle()
            }
        }
        .sheet(isPresented: $isShowSheet, content: {
            StyleSheetView(typeIndex: typeIndex ?? 0)
        })
    }
    
    private func detectType() {
        performTypesPrediction(onImage: image) { results in
            if let filteredResults = results.max(by: { $0.value < $1.value }) {
                selectedType = filteredResults.key
            }
        }
    }
    
    private func detectStyle() {
        if let index = typeIndex {
            performStylesPrediction(index: index, onImage: image) { results in
                print(results)
                if let filteredResults = results.max(by: { $0.value < $1.value }) {
                    selectedStyle.insert(filteredResults.key)
                }
            }
        }
    }
    
    private func generateResult() -> String {
        let filteredResult = [
            selectedType,
            selectedThickness,
            selectedColors.joined(separator: "，"),
            selectedStyle.joined(separator: "，")
        ].filter { !$0.isEmpty }
        return filteredResult.joined(separator: "，")
    }
}

#Preview {
    AnalysisView(image: UIImage(), isShowingCamera: .constant(false), isUploadPhoto: .constant(false))
        .environmentObject(CaptureViewModel())
        .environmentObject(ClothStylesViewModel())
}

#Preview {
    AnalysisView(image: UIImage(), isShowingCamera: .constant(false), isUploadPhoto: .constant(false))
        .environmentObject(CaptureViewModel())
        .environmentObject(ClothStylesViewModel())
        .preferredColorScheme(.dark)
}
